/*******************************************************************************
 * Copyright (c) 2007 University of Oslo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     University of Oslo - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.sequence.sedi.model.command;

import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.createUniqueName;
import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.getOwnedElements;
import static com.cea.papyrus.diagram.sequence.sedi.model.util.ModelUtil.getPackagedElements;

import org.eclipse.gef.commands.Command;
import org.eclipse.uml2.uml.DestructionEvent;
import org.eclipse.uml2.uml.Event;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.InteractionFragment;
import org.eclipse.uml2.uml.InteractionOperand;
import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.OccurrenceSpecification;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.utils.Debug;

/**
 * Command to create instances of DestructionEvents.
 * 
 * <p>
 * The following attributes can be read to access the result of the command:
 * </p>
 * <ul>
 * <li>Stop
 * </ul>
 * 
 * @author frankd@ifi.uio.no
 */
public class CreateStopCommand extends Command {

	private InteractionFragment owner;
	private OccurrenceSpecification stopOccurrence;
	private Lifeline coveredLifeline;

	public OccurrenceSpecification getStop() {
		return stopOccurrence;
	}
	
	/**
	 * This method should not be used...
	 * use CreateStopCommand(
	 * 				Lifeline coveredLifeline, 
	 * 				InteractionFragment owner)
	 * 
	 * instead
	 */
	public CreateStopCommand() {
		super();
		Debug.log(new Exception("This method should not be used."));
	}
	
	/**
	 * Main constructor
	 * @param coveredLifeline the {@link Lifeline} covered by the new {@link OccurenceSpecification}
	 * @param namespace the {@link Interaction} where the {@link OccurenceSpecification} is created
	 */
	public CreateStopCommand(Lifeline coveredLifeline, InteractionFragment owner) {
		super();
		this.coveredLifeline = coveredLifeline;
		if (!(owner instanceof Interaction || owner instanceof InteractionOperand)) {
			throw new IllegalArgumentException(String.valueOf(owner));
		}
		this.owner = owner;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void execute() {
		stopOccurrence = UMLFactory.eINSTANCE.createOccurrenceSpecification();
		stopOccurrence.setName(
				createUniqueName(
						getOwnedElements(owner),
						"DestructionOccurrenceSpecification_"));
		stopOccurrence.getCovereds().add(coveredLifeline);

		// Create a DestructionEvent associated with the StopOccurence
		DestructionEvent stopEvent;
		
		stopEvent = UMLFactory.eINSTANCE.createDestructionEvent();
		stopEvent.setName(
				createUniqueName(
						owner.getNearestPackage(),
						"DestructionEvent_"));
		getPackagedElements(owner.getNearestPackage()).add(stopEvent);

		stopOccurrence.setEvent(stopEvent);

		if (owner instanceof Interaction) {
			((Interaction) owner).getFragments().add(stopOccurrence); 
		} else if (owner instanceof InteractionOperand) {
			((InteractionOperand) owner).getFragments().add(stopOccurrence); 
		} else {
			Debug.log(new Exception("Unexpected owner type."));
		}
	}

	@Override
	public void undo() {
		Event stopEvent = stopOccurrence.getEvent();

		getPackagedElements(owner.getNearestPackage()).remove(stopEvent);

		if (owner instanceof Interaction) {
			((Interaction) owner).getFragments().remove(stopOccurrence); 
		} else if (owner instanceof InteractionOperand) {
			((InteractionOperand) owner).getFragments().remove(stopOccurrence); 
		} else {
			Debug.log(new Exception("Unexpected owner type."));
		}
	}

	@Override
	public void redo() {
		Event stopEvent = stopOccurrence.getEvent();
		getPackagedElements(owner.getNearestPackage()).add(stopEvent);
		
		if (owner instanceof Interaction) {
			((Interaction) owner).getFragments().add(stopOccurrence); 
		} else if (owner instanceof InteractionOperand) {
			((InteractionOperand) owner).getFragments().add(stopOccurrence); 
		} else {
			Debug.log(new Exception("Unexpected owner type."));
		}
	}

	@Override
	public void dispose() {
		stopOccurrence = null;
		owner = null;
	}
}
